//==================================================================
//  Copyright (C) 2006-2007  Davide Pasca
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//==================================================================
/// @file
///
///
/// 
/// @author Davide Pasca
/// 
//==================================================================

#ifndef REND_DEVICE_H
#define REND_DEVICE_H

#ifdef TARGET_D3D
#include <direct3d.h>
#endif
#include "psys.h"
#include "rend_device_state.h"
#include "rend_offscr.h"
#include "rend_shaders.h"

//==================================================================
#ifdef TARGET_D3D
typedef IDirect3D9	RendSystemContext;
#else
typedef void		RendSystemContext;
#endif

//==================================================================
///
//==================================================================
class RendDevice
{
	int							_disp_w, _disp_h;
#ifdef TARGET_D3D
	com_ptr<D3DDevice>			_d3ddevp;

	com_ptr<D3DTexture>			_front_buff_texturep;
	com_ptr<D3DTexture>			_resolve_texturep;

	com_ptr<D3DTexture>			_pproc_downsample4x4_texturep;
	com_ptr<D3DTexture>			_pproc_downsample8x8_texturep;
	com_ptr<D3DTexture>			_pproc_bloom_texture1p;
	com_ptr<D3DTexture>			_pproc_bloom_texture2p;

	com_ptr<D3DSurface>			_final_rendtarget_surfp;

	int							_cur_buff_idx;

#endif
	RendTarget					*_rend_special_targetp;
	bool						_bloom_onoff;
	float						_bloom_brightness;
	float						_bloom_bright_threshold;

public:
	RendDeviceState				_DrawState;
	RendShaderManager			_ShaderMng;

public:
	RendDevice( RendSystemContext *contextp, u_int w, u_int h, const TCHAR *basepathp );

	RendTarget	*NewRendTarget( u_int w, u_int h, const RendTarget::CreationParams &params );

	void	RenderBegin( RendTarget *special_targetp=NULL );
	void	RenderEnd();

	void	SelectVertexBuffer( class RendVertexBuffer *vbuffp )
	{
		_ShaderMng.SelectVertexBuffer( vbuffp );
	}

	void	SetBloom( bool onoff, float brightness, float bright_threshold )
	{
		_bloom_onoff = onoff;
		_bloom_brightness = brightness;
		_bloom_bright_threshold = bright_threshold;
	}
	bool	GetBloomOnOff() const
	{
		return _bloom_onoff;
	}
	float	GetBloomBrightness() const
	{
		return _bloom_brightness;
	}
	float	GetBloomBrightThreshold() const
	{
		return _bloom_bright_threshold;
	}

#ifdef WIN32
	void	SwapBuffers( void *hdc );
#endif


#ifdef TARGET_D3D
	D3DDevice	*GetD3DDevice()
	{
		return _d3ddevp;
	}
#endif

	bool	IsRendering() const	{	return _is_rendering;	}

	u_int	GetWidth() const
	{
		return _disp_w;
	}

	u_int	GetHeight() const
	{
		return _disp_h;
	}

private:
	bool	_is_rendering;

#ifdef TARGET_D3D
	void	renderTextureToFinalSimple( D3DTexture *src_texp );
	void	renderTextureToFinalBloom( D3DTexture *src_base_texp, D3DTexture *src_bloom_texp );
	void	beginPostProcessing();
	void	renderDS4x4Texture( D3DTexture *desp, D3DTexture *srcp, u_int src_w, u_int src_h );
	void	renderDS2x2Texture( D3DTexture *desp, D3DTexture *srcp, u_int src_w, u_int src_h );
	void	renderBloomTexture(	D3DTexture *desp,
								D3DTexture *srcp,
								u_int src_w, u_int src_h, bool is_horiz,
								float brightness,
								float bright_threshold );
	void	createRendTargetD3D( RendSystemContext *contextp, int w, int h );
	void	renderBeginD3D();
	void	renderEndD3DSwap();
#endif
};

#endif
